<?php
/**
 * App 登录
 *
 * Author: Zeon
 * Date: 2017/11/20
 * Created by Panxsoft.
 */
namespace App\Http\Middleware;

use App\Models\Admin;
use App\Models\User;
use App\Services\Locale\AppLanguage;
use App\Services\Utils\Guard;
use Closure;
use Illuminate\Http\Request;

class LocaleEnv
{
    const HEADER_TIMEZONE_OFFSET_KEY = 'X-Timezone-Offset';
    const MAX_TIMEZONE_OFFSET = 720;

    /**
     * 请求头中的时区偏移
     * @var int
     */
    static protected $timezone_offset = 0; 

    /**
     *
     * @example composer require tymon/jwt-auth@1.0.0-beta.3
     * @link http://jwt-auth.readthedocs.io/en/docs/quick-start/
     *
     * @param Request $request
     * @param Closure $next
     * @param $guard_name
     *
     * @return mixed
     */
    public function handle(Request $request, Closure $next, string $guard_name = null)
    {
        $language = $request->get('language')
            ?: $request->get('lang')
            ?: $this->getGuardUserLanguage($guard_name)
            ?: AppLanguage::headerFirstAcceptLanguage()
            ?: AppLanguage::DEFAULT_LOCALE;

        AppLanguage::setAppLocale($language);

        self::setTimezoneOffset($request);

        return $next($request);
    }

    /**
     * @param $guard_name
     *
     * @return mixed
     */
    private function getGuardUserLanguage(?string $guard_name): ?string
    {
        switch ($guard_name) {
            case Admin::GUARD_NAME :
                return $this->getAdminLanguage();
            case User::GUARD_NAME :
                return $this->getUserLanguage();
            default :
                return null;
        }
    }

    private function getAdminLanguage()
    {
        return Guard::admin()->language->code ?? null;
    }

    private function getUserLanguage()
    {
        return Guard::user()->language->code ?? null;
    }

    protected function setTimezoneOffset(Request $request): void
    {
        $offset = $request->header(self::HEADER_TIMEZONE_OFFSET_KEY);

        if ($offset &&
            is_numeric($offset) &&
            (abs($offset) <= self::MAX_TIMEZONE_OFFSET))
        {
            self::$timezone_offset = (int) $offset;
        }
    }

    static public function timezoneOffset(): int
    {
        return self::$timezone_offset;
    }
}
